package profiler.config;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.HashSet;

import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.io.xml.DomDriver;

/**
 * The Class ProfilerConfig stores information about the classes (and its methods) that must be
 * profiled by the Profiler ({@link profiler.main.Main})
 */
public class ProfilerConfig {
	// HashSet used to contain all the methods whose must be profiled
	/** The classes. */
	HashSet<MethodDeclaration> methods = new HashSet<MethodDeclaration>();
	
	
	/**
	 * Instantiates a new profiler config.
	 */
	public ProfilerConfig() {
		
	}
	
	/**
	 * Instantiates a new profiler config and fills it with the information stored in the given file.
	 *
	 * @param xmlFile the xml file where a ProfilerConfig have been serialized using XStream
	 */
	public ProfilerConfig(String xmlFile) {
        XStream xs = new XStream(new DomDriver());
        xs.alias("Method", profiler.config.MethodDeclaration.class);
        
        try {
        	FileInputStream fis = new FileInputStream(xmlFile);
    		
            methods = (HashSet<MethodDeclaration>)xs.fromXML(fis);
            
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
	
	/**
	 * Adds a new method declaration to the profiler configuration. This methods
	 * will be profiled.
	 *
	 * @param m the method to be added
	 */
	public void addMethodDeclaration(MethodDeclaration m) {
		methods.add(m);
	}
	
	/**
	 * Checks if the profilerConfig contains the given method.
	 *
	 * @param className the class name
	 * @param methodName the method name
	 * @param descriptor the method descriptor
	 * @return true, if successful
	 */
	public boolean containsMethod(String className, String methodName, String descriptor) {
			return methods.contains(new MethodDeclaration(className, methodName, descriptor));		
	}
	
	/**
	 * Checks if the profilerConfig contains the given method.
	 *
	 * @param m the m
	 * @return true, if successful
	 */
	public boolean containsMethod(MethodDeclaration m) {
			return methods.contains(m);		
	}
	
	/**
	 * Serialize the object to a XML file with the information stored in the ProfilerConfig. It can be deserialized creating 
	 * a ProfilerConfig with the XML file as argument. 
	 * 
	 * @param fileName the file name
	 */
	public void toXML(String fileName) {
		// Creo el flujo de salida en XML para serializar el objeto
		XStream xs = new XStream(new DomDriver());
		xs.alias("Method", profiler.config.MethodDeclaration.class);
		
        // Escribo el objeto serializado en un archivo de salida
        try {
            FileOutputStream fs = new FileOutputStream(fileName);
            xs.toXML(methods, fs);
        } catch (FileNotFoundException e1) {
            e1.printStackTrace();
        }
	}
	
}
